package customerController

import (
	"WEB/models"
	"fmt"
	"github.com/astaxie/beego/orm"
	uuid "github.com/satori/go.uuid"
	"github.com/tidwall/gjson"
	"strings"
)

type OrderContoller struct {
	BaseController
}

// @router /customer/makeOrder [post]
func (this *OrderContoller) MakeOrder() {
	/*
		1.  判断数量够不够
		2.  生成订单
		3.  生成订单项
		4.  修改数量 删除购物车
	*/
	data := this.GetStrings("item")
	orderItems := make([]models.OrderItem, len(data))
	user := this.GetSession("User").(models.User)

	var sql string
	newOrm := orm.NewOrm()

	reponse := models.ResponseBody{
		Code: 0,
	}
	//1. check
	goods := make([]models.Goods, len(data))
	orderIdMap := map[int64]string{}
	for i, v := range data {
		itemNums := gjson.Get(v, "ItemNums").Int()
		itemPrices := gjson.Get(v, "ItemPrices").Float()
		itemGoodsId := gjson.Get(v, "ItemGoodsId").Int()
		itemStoreId := gjson.Get(v, "ItemStoreId").Int()
		orderItems[i].ItemUserId = user.UserId
		orderItems[i].ItemGoodsId = int(itemGoodsId)
		orderItems[i].ItemPrices = itemPrices
		orderItems[i].ItemNums = int(itemNums)

		s, ok := orderIdMap[itemStoreId]
		if ok {
			orderItems[i].ItemOrderId = s
		} else {
			num := uuid.Must(uuid.NewV4())
			orderItems[i].ItemOrderId = num.String()
			orderIdMap[itemStoreId] = num.String()
		}

		sql = `
				SELECT *
				FROM goods
				WHERE good_id = ? and good_storage >= ?
				`
		e := newOrm.Raw(sql, itemGoodsId, orderItems[i].ItemNums).QueryRow(&goods[i])
		if e != nil {
			reponse.Code = 1
			reponse.Msg = "数量不足"
			this.Data["json"] = reponse
			this.ServeJSON()
			return
		}
	}
	//2. make order
	for k, v := range orderIdMap {
		sql = `
			INSERT INTO orders 
			(order_id,order_user_id,order_status,order_store_id) 
			values 
			(?,?,?,?) 
			`
		fmt.Println(sql)
		_, e := newOrm.Raw(sql, v, user.UserId, "需添加收件信息", k).Exec()
		if e != nil {
			panic(e)
		}
	}

	//3. make order_item
	for i := 0; i < len(data); i++ {
		sql = models.InsertIntoTable(orderItems[i])
		_, e := newOrm.Raw(sql, models.GetFieldValue(orderItems[i], models.IsNothing)).Exec()
		if e != nil {
			panic(e)
		}
		sql = `
					UPDATE goods
					SET good_storage = ? , good_count = ?
					WHERE good_id = ?
				`
		remain := goods[i].GoodStorage - orderItems[i].ItemNums
		sellNum := goods[i].GoodCount + orderItems[i].ItemNums
		_, e = newOrm.Raw(sql, remain, sellNum, goods[i].GoodId).Exec()
		if e != nil {
			reponse.Code = 1
			reponse.Msg = "数量不足"
			this.Data["json"] = reponse
			this.ServeJSON()
			return
		}
	}

	for _, v := range data {
		shopId := gjson.Get(v, "ShopId").Int()
		sql = models.DeleteByField(models.ShopCard{}, "ShopCardId")
		_, e := newOrm.Raw(sql, shopId).Exec()
		if e != nil {
			panic(e)
		}
	}
	reponse.Code = 0
	list := make([]string, len(orderIdMap))
	cnt := 0
	for _, v := range orderIdMap {
		list[cnt] = "orderId=" + v
		cnt++
	}
	url := strings.Join(list, "&")
	reponse.Data = map[string]string{"url": url}
	this.Data["json"] = reponse
	this.ServeJSON()
	//
}

// @router /customer/orderList [get]
func (this *OrderContoller) GetPage() {
	user := this.GetSession("User").(models.User)
	var orders []models.Orders
	sql := models.QueryByEqualField(models.Orders{}, "OrderUserId")
	newOrm := orm.NewOrm()
	_, e := newOrm.Raw(sql, user.UserId).QueryRows(&orders)
	if e != nil {
		panic(e)
	}
	for i, v := range orders {
		var items []models.OrderItem
		sql = models.QueryByEqualField(models.OrderItem{}, "ItemOrderId")
		_, e := newOrm.Raw(sql, v.OrderId).QueryRows(&items)
		if e != nil {
			panic(e)
		}
		sum := 0.0
		for ii, vv := range items {
			var good models.Goods
			sql = models.QueryByEqualField(models.Goods{}, "GoodId")
			e := newOrm.Raw(sql, vv.ItemGoodsId).QueryRow(&good)
			if e != nil {
				panic(e)
			}
			items[ii].GoodItem = good
			items[ii].ItemSum = float64(items[ii].ItemNums) * (items[ii].ItemPrices)
			sum = sum + items[ii].ItemSum
		}
		orders[i].OrderItems = items
		orders[i].OrderSumPrices = sum
	}
	this.Data["Orders"] = orders
	this.TplName = "customer/orders.html"
}

// @router /customer/orderEx [get]
func (this *OrderContoller) GetOrderEx() {

	orderId := this.GetString("orderId")
	this.Data["OrderId"] = orderId
	this.TplName = "customer/orderExternal.html"
}

// @router /customer/addOrderEx [post]
func (this *OrderContoller) PostEx() {

	orderId := this.GetStrings("orderId")
	for _, v := range orderId {
		newOrm := orm.NewOrm()
		var temp models.Orders
		sql := models.QueryByPrimaryKey(temp)
		e := newOrm.Raw(sql, orderId).QueryRow(&temp)
		if e != nil {
			panic(e)
		}

		if err := this.ParseForm(&temp); err != nil {
			panic(err)
		}
		temp.OrderId = v
		temp.OrderStatus = "已下单"
		sql = models.UpdateByPrimaryKey(temp)
		_, e = newOrm.Raw(sql, models.GetFieldValue(temp, models.IsPrimaryKey), orderId).Exec()
		if e != nil {
			panic(e)
		}
	}
	this.Redirect("/customer/ok", 302)
}

// @router /customer/ok [get]
func (this *OrderContoller) GetOk() {
	this.TplName = "customer/ok.html"
}

// @router /customer/orderNow [post]
func (this *OrderContoller) OrderNow() {
	//商品下单
	//商品id 和 数目

	data := this.GetStrings("item")
	orderItems := make([]models.OrderItem, len(data))
	user := this.GetSession("User").(models.User)

	var sql string
	newOrm := orm.NewOrm()

	reponse := models.ResponseBody{
		Code: 0,
	}
	if len(data) != 1 {
		reponse.Code = 1
		reponse.Msg = "未知错误"
		this.Data["json"] = reponse
		this.ServeJSON()
	}
	//1. check
	goods := make([]models.Goods, len(data))
	orderIdMap := map[int64]string{}
	for i, v := range data {
		itemNums := gjson.Get(v, "ItemNums").Int()
		itemPrices := gjson.Get(v, "ItemPrices").Float()
		itemGoodsId := gjson.Get(v, "ItemGoodsId").Int()
		itemStoreId := gjson.Get(v, "ItemStoreId").Int()
		orderItems[i].ItemUserId = user.UserId
		orderItems[i].ItemGoodsId = int(itemGoodsId)
		orderItems[i].ItemPrices = itemPrices
		orderItems[i].ItemNums = int(itemNums)

		s, ok := orderIdMap[itemStoreId]
		if ok {
			orderItems[i].ItemOrderId = s
		} else {
			num := uuid.Must(uuid.NewV4())
			orderItems[i].ItemOrderId = num.String()
			orderIdMap[itemStoreId] = num.String()
		}

		sql = `
				SELECT *
				FROM goods
				WHERE good_id = ? and good_storage >= ?
				`
		e := newOrm.Raw(sql, itemGoodsId, orderItems[i].ItemNums).QueryRow(&goods[i])
		if e != nil {
			reponse.Code = 1
			reponse.Msg = "数量不足"
			this.Data["json"] = reponse
			this.ServeJSON()
			return
		}
	}
	//2. make order
	for k, v := range orderIdMap {
		sql = `
			INSERT INTO orders 
			(order_id,order_user_id,order_status,order_store_id) 
			values 
			(?,?,?,?) 
			`
		fmt.Println(sql)
		_, e := newOrm.Raw(sql, v, user.UserId, "需添加收件信息", k).Exec()
		if e != nil {
			panic(e)
		}
	}

	//3. make order_item
	for i := 0; i < len(data); i++ {
		sql = models.InsertIntoTable(orderItems[i])
		_, e := newOrm.Raw(sql, models.GetFieldValue(orderItems[i], models.IsNothing)).Exec()
		if e != nil {
			panic(e)
		}
		sql = `
					UPDATE goods
					SET good_storage = ? , good_count = ?
					WHERE good_id = ?
				`
		remain := goods[i].GoodStorage - orderItems[i].ItemNums
		sellNum := goods[i].GoodCount + orderItems[i].ItemNums
		_, e = newOrm.Raw(sql, remain, sellNum, goods[i].GoodId).Exec()
		if e != nil {
			reponse.Code = 1
			reponse.Msg = "数量不足"
			this.Data["json"] = reponse
			this.ServeJSON()
			return
		}
	}
	reponse.Code = 0
	list := make([]string, len(orderIdMap))
	cnt := 0
	for _, v := range orderIdMap {
		list[cnt] = "orderId=" + v
		cnt++
	}
	url := strings.Join(list, "&")
	reponse.Data = map[string]string{"url": url}
	this.Data["json"] = reponse
	this.ServeJSON()
	//
}

// @router /customer/receiveOrder [post]
func (this *OrderContoller) ReceiveOrder() {
	orderId := this.GetString("orderId")
	newOrm := orm.NewOrm()
	var temp models.Orders
	sql := models.QueryByPrimaryKey(temp)
	e := newOrm.Raw(sql, orderId).QueryRow(&temp)
	if e != nil {
		this.Data["json"] = map[string]interface{}{
			"code": 1,
		}
		this.ServeJSON()
		return
	}
	user := this.GetSession("User").(models.User)
	if temp.OrderUserId != user.UserId {
		this.Data["json"] = map[string]interface{}{
			"code": 1,
		}
		this.ServeJSON()
		return
	}

	sql = models.UpdateFieldsByPrimary(temp, "OrderStatus")
	_, e = newOrm.Raw(sql, "已收货", orderId).Exec()
	if e != nil {
		this.Data["json"] = map[string]interface{}{
			"code": 1,
		}
		this.ServeJSON()
		return
	}
	this.Data["json"] = map[string]interface{}{
		"code": 0,
	}
	this.ServeJSON()
}
